// 防止在 Windows 上的 release 版本中出现额外的控制台窗口
// (Rust 特有的属性语法，JavaScript 中没有类似功能)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

// 引入所需的库
// (在 Rust 中，使用 use 语句来引入库，类似于 JavaScript 的 import 语句)
#[allow(unused_imports)]
use serde::{Deserialize, Serialize};
use serde_json;
use std::fs;
use std::process::Command;
use std::thread;
use sysinfo::System;
use tauri::State;
// 定义一个可序列化的结构体，用于存储系统信息
// (Rust 使用 struct 关键字定义结构体，这是 Rust 特有的数据结构，不同于 JavaScript 的对象)
#[derive(Serialize, Deserialize)]
struct SysInfo {
    total_memory: u64,
    used_memory: u64,
    total_swap: u64,
    used_swap: u64,
    processor_name: String,
}
#[derive(Serialize, Deserialize)]
struct FileInfo {
    file_name: String,
    file_type: String,
    file_size: u64,
}
// Tauri 命令，返回一个问候语
// (Rust 函数定义使用 fn 关键字，参数类型需要显式声明，不同于 JavaScript)
#[tauri::command]
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

// Tauri 命令，获取并返回系统信息
// (使用 State 包装 System，来在 Tauri 应用中管理共享状态，这是 Rust 特有的功能)
#[tauri::command]
fn get_sys_info(sys: State<System>) -> String {
    let sys_info = SysInfo {
        total_memory: sys.total_memory(),
        used_memory: sys.used_memory(),
        total_swap: sys.total_swap(),
        used_swap: sys.used_swap(),
        processor_name: sys.global_cpu_info().brand().to_string(),
    };

    serde_json::to_string(&sys_info).expect("Failed to serialize system info")
}
#[tauri::command]
fn get_file_infos(path: String) -> Result<Vec<FileInfo>, String> {
    let mut file_infos: Vec<FileInfo> = Vec::new();

    if let Ok(entries) = fs::read_dir(path) {
        for entry in entries {
            if let Ok(entry) = entry {
                if let Ok(file_name) = entry.file_name().into_string() {
                    let file_type = if entry.file_type().unwrap().is_dir() {
                        "directory".to_string()
                    } else {
                        "file".to_string()
                    };
                    let file_size = if let Ok(metadata) = entry.metadata() {
                        metadata.len()
                    } else {
                        0
                    };

                    let file_info = FileInfo {
                        file_name,
                        file_type,
                        file_size,
                    };

                    file_infos.push(file_info);
                }
            }
        }

        Ok(file_infos)
    } else {
        Err("Failed to read directory".to_string())
    }
}

// Tauri 命令，执行一个系统命令并返回命令的输入字符串
// (Rust 中的错误处理使用 expect，这是 Rust 的错误处理机制，不同于 JavaScript 的 try-catch)
// #[tauri::command]
// fn my_custom_command(invoke_message: String) -> String {
//     let _output = Command::new(invoke_message.clone())
//         .output()
//         .expect("Failed to execute command");

//     invoke_message
// }
#[tauri::command]
fn my_custom_command(invoke_message: String) -> String {
    // 在新线程中执行命令
    thread::spawn(move || {
        Command::new(invoke_message)
            .spawn() // 使用 spawn 而不是 output 来非阻塞地运行命令
            .expect("Failed to execute command");
    });

    // 你可以立即返回，而命令会在后台运行
    "Command executed in background".to_string()
}
// Tauri 命令，检查并返回运行的操作系统
// (Rust 使用宏 cfg! 来进行条件编译，这是 Rust 特有的功能)
#[tauri::command]
fn check_os() -> String {
    if cfg!(target_os = "windows") {
        "Windows".to_string()
    } else if cfg!(target_os = "macos") {
        "macOS".to_string()
    } else {
        "Other OS".to_string()
    }
}

// 程序入口点，设置 Tauri 应用程序
// (Rust 的 main 函数是程序的入口点，类似于 JavaScript，但必须显式声明)
fn main() {
    tauri::Builder::default()
        .manage(System::new_all()) // 管理系统信息状态
        .invoke_handler(tauri::generate_handler![
            greet,
            my_custom_command,
            check_os,
            get_file_infos
        ]) // 配置可调用的命令
        .run(tauri::generate_context!()) // 启动应用程序
        .expect("error while running tauri application")
}
